home *** CD-ROM | disk | FTP | other *** search
/ Cream of the Crop 26 / Cream of the Crop 26.iso / os2 / timidsrc.zip / getopt.c < prev    next >
C/C++ Source or Header  |  1996-05-20  |  4KB  |  138 lines

  1. /*
  2.     Copyright (c) 1986,1992 by Borland International Inc.
  3.     All Rights Reserved.
  4. */
  5.  
  6. #include <errno.h>
  7. #include <string.h>
  8. #include <dos.h>
  9. #include <stdio.h>
  10.  
  11. int    optind    = 1;    /* index of which argument is next    */
  12. char   *optarg;        /* pointer to argument of current option */
  13. int    opterr    = 1;    /* allow error message    */
  14.  
  15. static    char   *letP = NULL;    /* remember next option char's location */
  16.  
  17. #if 0
  18. static    char    SW = 0;        /* DOS switch character, either '-' or '/' */
  19. #endif
  20. #define SW '-' /* On Win32 can't call DOS! */
  21. /*
  22.   Parse the command line options, System V style.
  23.  
  24.   Standard option syntax is:
  25.  
  26.     option ::= SW [optLetter]* [argLetter space* argument]
  27.  
  28.   where
  29.     - SW is either '/' or '-', according to the current setting
  30.       of the MSDOS switchar (int 21h function 37h).
  31.     - there is no space before any optLetter or argLetter.
  32.     - opt/arg letters are alphabetic, not punctuation characters.
  33.      - optLetters, if present, must be matched in optionS.
  34.     - argLetters, if present, are found in optionS followed by ':'.
  35.     - argument is any white-space delimited string.  Note that it
  36.       can include the SW character.
  37.     - upper and lower case letters are distinct.
  38.  
  39.   There may be multiple option clusters on a command line, each
  40.   beginning with a SW, but all must appear before any non-option
  41.   arguments (arguments not introduced by SW).  Opt/arg letters may
  42.   be repeated: it is up to the caller to decide if that is an error.
  43.  
  44.   The character SW appearing alone as the last argument is an error.
  45.   The lead-in sequence SWSW ("--" or "//") causes itself and all the
  46.   rest of the line to be ignored (allowing non-options which begin
  47.   with the switch char).
  48.  
  49.   The string *optionS allows valid opt/arg letters to be recognized.
  50.   argLetters are followed with ':'.  Getopt () returns the value of
  51.   the option character found, or EOF if no more options are in the
  52.   command line.     If option is an argLetter then the global optarg is
  53.   set to point to the argument string (having skipped any white-space).
  54.  
  55.   The global optind is initially 1 and is always left as the index
  56.   of the next argument of argv[] which getopt has not taken.  Note
  57.   that if "--" or "//" are used then optind is stepped to the next
  58.   argument before getopt() returns EOF.
  59.  
  60.   If an error occurs, that is an SW char precedes an unknown letter,
  61.   then getopt() will return a '?' character and normally prints an
  62.   error message via perror().  If the global variable opterr is set
  63.   to false (zero) before calling getopt() then the error message is
  64.   not printed.
  65.  
  66.   For example, if the MSDOS switch char is '/' (the MSDOS norm) and
  67.  
  68.     *optionS == "A:F:PuU:wXZ:"
  69.  
  70.   then 'P', 'u', 'w', and 'X' are option letters and 'F', 'U', 'Z'
  71.   are followed by arguments.  A valid command line may be:
  72.  
  73.     aCommand  /uPFPi /X /A L someFile
  74.  
  75.   where:
  76.     - 'u' and 'P' will be returned as isolated option letters.
  77.     - 'F' will return with "Pi" as its argument string.
  78.     - 'X' is an isolated option.
  79.     - 'A' will return with "L" as its argument.
  80.     - "someFile" is not an option, and terminates getOpt.  The
  81.       caller may collect remaining arguments using argv pointers.
  82. */
  83.  
  84. int    getopt(int argc, char *argv[], char *optionS)
  85. {
  86.     unsigned char ch;
  87.     char *optP;
  88.  
  89. #if 0
  90.     if (SW == 0) {
  91.         /* get SW using dos call 0x37 */
  92.         _AX = 0x3700;
  93.         geninterrupt(0x21);
  94.         SW = _DL;
  95.     }
  96. #endif
  97.     if (argc > optind) {
  98.         if (letP == NULL) {
  99.             if ((letP = argv[optind]) == NULL ||
  100.                 *(letP++) != SW)  goto gopEOF;
  101.             if (*letP == SW) {
  102.                 optind++;  goto gopEOF;
  103.             }
  104.         }
  105.         if (0 == (ch = *(letP++))) {
  106.             optind++;  goto gopEOF;
  107.         }
  108.         if (':' == ch  ||  (optP = strchr(optionS, ch)) == NULL)
  109.             goto gopError;
  110.         if (':' == *(++optP)) {
  111.             optind++;
  112.             if (0 == *letP) {
  113.                 if (argc <= optind)  goto  gopError;
  114.                 letP = argv[optind++];
  115.             }
  116.             optarg = letP;
  117.             letP = NULL;
  118.         } else {
  119.             if (0 == *letP) {
  120.                 optind++;
  121.                 letP = NULL;
  122.             }
  123.             optarg = NULL;
  124.         }
  125.         return ch;
  126.     }
  127. gopEOF:
  128.     optarg = letP = NULL;  
  129.     return EOF;
  130.  
  131. gopError:
  132.     optarg = NULL;
  133.     errno  = EINVAL;
  134.     if (opterr)
  135.         perror ("get command line option");
  136.     return ('?');
  137. }
  138.